package com.openingedu.mba.service;

import java.util.WeakHashMap;
import java.util.concurrent.Future;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

import com.openingedu.mba.service.task.TaskCallback;
import com.openingedu.mba.service.task.TaskInvokeCallback;
import com.openingedu.mba.service.task.TaskInvoker;
import com.openingedu.mba.service.task.impl.TaskQueueConsumer;

public class BackendService extends Service {

	private static final String TAG = BackendService.class.getSimpleName();

	/** 线程池 **/
	private ThreadPoolExecutor mThreadPool;
	private WeakHashMap<Integer, Future<?>> mThreadMaping;

	private Integer mThreadId = 0;
	private TaskInvokeCallback mTaskInvokeCallback;

	private static final int DEF_THREAD_POOL_SIZE = 2;
	private static final int MAX_THREAD_POOL_SIZE = 8;
	private static final int KEEP_ALIVE_TIME = 60;

	@Override
	public IBinder onBind(Intent arg0) {
		return null;
	}

	@Override
	public void onCreate() {
		super.onCreate();
		Log.i(TAG, "backend service started...");
		mThreadMaping = new WeakHashMap<Integer, Future<?>>();
		mTaskInvokeCallback = new TaskInvokeCallback(){
			@Override
			public void sendMessage(int requestId) {
//				cancleRequest(requestId);
				mThreadMaping.remove(requestId);
			}
        };
		mThreadPool = new ThreadPoolExecutor(DEF_THREAD_POOL_SIZE,
				MAX_THREAD_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS,
				new SynchronousQueue<Runnable>(),
				new ThreadPoolExecutor.CallerRunsPolicy());
		initConsumer();
	}

	private void initConsumer() {
		TaskCallback callback = new TaskCallback() {

			@Override
			public void onStart(Object obj) {
				invokeTask((TaskInvoker)obj);
			}
			
		};
		TaskInvoker consumerTask = new TaskQueueConsumer(callback);
		consumerTask.setExecutionCallback(mTaskInvokeCallback);
		invokeTask(consumerTask);
	}

	/**
	 * 执行请求
	 * 
	 * @param uriRequest
	 *            请求对象
	 * @param callback
	 *            回调接口
	 */
	private int invokeTask(TaskInvoker taskInvoker) {
		
		int threadId = 0;
		synchronized (mThreadId) {
			threadId = mThreadId;
			mThreadId++;
		}
		
		taskInvoker.setThreadId(threadId);
		
		Future<?> thread = mThreadPool.submit(taskInvoker);
		synchronized(mThreadMaping){
			mThreadMaping.put(threadId, thread);
		}
		
		return threadId;
	}

}
